wayland: Use the wl_display_sync() request to track pending init roundtrips
authorKristian Høgsberg <krh@bitplanet.net>
Wed, 27 Mar 2013 17:38:15 +0000 (13:38 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Wed, 27 Mar 2013 17:44:33 +0000 (13:44 -0400)
Instead of maintaining the init refcount in regular event handlers that can
fire in case of hotplug or mode changes, use a dedicated sync callback
to wait for roundtrips.

gdk/wayland/gdkdevice-wayland.c
gdk/wayland/gdkdisplay-wayland.c
gdk/wayland/gdkscreen-wayland.c

index 2c14bc1321ef6db98472c9ed35710b48d4af7d45..4c8caecc2d715063f8c2e3813a4f1a29a96db2e7 100644 (file)
@@ -1107,7 +1107,6 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
   GdkWaylandDeviceData *device = data;
   GdkWaylandDeviceManager *device_manager =
     GDK_WAYLAND_DEVICE_MANAGER(device->device_manager);
-  GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
 
   if ((caps & WL_SEAT_CAPABILITY_POINTER) && !device->wl_pointer)
     {
@@ -1186,12 +1185,6 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
       _gdk_device_set_associated_device (device->pointer, device->keyboard);
       _gdk_device_set_associated_device (device->keyboard, device->pointer);
     }
-
-  /* Once we have the capabilities event we know we have all events
-   * from the wl_seat and need no further init roundtrips.
-   */
-  if (display->init_ref_count > 0)
-    display->init_ref_count--;
 }
 
 static const struct wl_seat_listener seat_listener = {
index 0e4701e59838fb0a0a6a477831d98a389b7fa968..22d282d137568a441bd97044b792d19a6d5f3283 100644 (file)
@@ -88,6 +88,29 @@ gdk_input_init (GdkDisplay *display)
   g_list_free (list);
 }
 
+static void
+init_sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
+{
+  GdkWaylandDisplay *display = data;
+
+  display->init_ref_count--;
+  wl_callback_destroy(callback);
+}
+
+static const struct wl_callback_listener init_sync_listener = {
+       init_sync_callback
+};
+
+static void
+wait_for_roundtrip(GdkWaylandDisplay *display)
+{
+  struct wl_callback *callback;
+
+  display->init_ref_count++;
+  callback = wl_display_sync(display->wl_display);
+  wl_callback_add_listener(callback, &init_sync_listener, display);
+}
+
 static void
 gdk_registry_handle_global(void *data, struct wl_registry *registry, uint32_t id,
                                        const char *interface, uint32_t version)
@@ -100,7 +123,6 @@ gdk_registry_handle_global(void *data, struct wl_registry *registry, uint32_t id
   if (strcmp(interface, "wl_compositor") == 0) {
     display_wayland->compositor =
        wl_registry_bind(display_wayland->wl_registry, id, &wl_compositor_interface, 1);
-    display_wayland->init_ref_count--;
   } else if (strcmp(interface, "wl_shm") == 0) {
    display_wayland->shm =
        wl_registry_bind(display_wayland->wl_registry, id, &wl_shm_interface, 1);
@@ -114,17 +136,17 @@ gdk_registry_handle_global(void *data, struct wl_registry *registry, uint32_t id
     output =
       wl_registry_bind(display_wayland->wl_registry, id, &wl_output_interface, 1);
     _gdk_wayland_screen_add_output(display_wayland->screen, id, output);
-    /* We need to roundtrip until we've received the modes and
-     * geometry events for the output, which gives us the physical
-     * properties and available modes on the output. */
-    display_wayland->init_ref_count++;
+    /* We need another roundtrip to receive the modes and geometry
+     * events for the output, which gives us the physical properties
+     * and available modes on the output. */
+    wait_for_roundtrip(display_wayland);
   } else if (strcmp(interface, "wl_seat") == 0) {
     seat = wl_registry_bind(display_wayland->wl_registry, id, &wl_seat_interface, 1);
     _gdk_wayland_device_manager_add_seat (gdk_display->device_manager, id, seat);
-    /* We need to roundtrip until we've received the wl_seat
-     * capabilities event which informs us of available input devices
-     * on this seat. */
-    display_wayland->init_ref_count++;
+    /* We need another roundtrip to receive the wl_seat capabilities
+     * event which informs us of available input devices on this
+     * seat. */
+    wait_for_roundtrip(display_wayland);
   } else if (strcmp(interface, "wl_data_device_manager") == 0) {
       display_wayland->data_device_manager =
         wl_registry_bind(display_wayland->wl_registry, id,
@@ -177,7 +199,7 @@ _gdk_wayland_display_open (const gchar *display_name)
 
   /* We use init_ref_count to track whether some part of our
    * initialization still needs a roundtrip to complete. */
-  display_wayland->init_ref_count = 1;
+  wait_for_roundtrip(display_wayland);
   while (display_wayland->init_ref_count > 0)
     wl_display_roundtrip(display_wayland->wl_display);
 
index ee4200b04bd8ea9100eedff270afa61f4c23be00..5c6c1dd527fa546b345c2f0ce7bd294d8bead4c3 100644 (file)
@@ -896,12 +896,6 @@ output_handle_geometry(void *data,
   monitor->manufacturer = g_strdup (make);
   monitor->output_name = g_strdup (model);
 
-  /* Once we have the geometry event we know we have all events
-   * from the wl_output and need no further init roundtrips.
-   */
-  if (display->init_ref_count > 0)
-    display->init_ref_count--;
-
   if (monitor->geometry.width != 0)
     {
       g_signal_emit_by_name (monitor->screen, "monitors-changed");